#ifndef DEFS_H_INCLUDED
#define DEFS_H_INCLUDED

#include <set>
#include <map>
#include <list>
#include <string>
#include <vector>
#include <memory>

using StringSet = std::set <std::string> ;
using ProductionList = std::list <StringSet::const_iterator>;
using ProductionMap = std::multimap <std::string, ProductionList>;
using FirstFollowSet = std::list <StringSet::const_iterator>;
using FirstFollowMap = std::map <std::string, FirstFollowSet>;
using PredMapLine = std::map <std::string, ProductionMap::const_iterator>;
using PredMap = std::map <std::string, PredMapLine>;

struct Item
{
    ProductionMap::const_iterator prod;
    ProductionList::const_iterator dot;

    bool operator == (const Item & rhs) const
    {
        return prod == rhs.prod && dot == rhs.dot;
    }
};

struct Closure
{
    Item item;
    StringSet::iterator lookahead;

    bool operator == (const Closure & rhs) const
    {
        return item == rhs.item && lookahead == rhs.lookahead;
    }
};

using ClosureList = std::list <Closure>;
using Collection = std::vector <std::unique_ptr<ClosureList>>;

#endif // DEFS_H_INCLUDED
